#pragma once

#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <d2d1.h>
#include <d2d1helper.h>
#include <atlbase.h>
#include <stdint.h>

#include <functional>

#ifndef HINST_THISCOMPONENT
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase)
#endif

#ifndef DxRoidsAssert
#if defined(DEBUG) || defined(_DEBUG)
#define DxRoidsAssert(EXP) if (!(EXP)) { OutputDebugStringA("ASSERT: " #EXP "\n"); DebugBreak(); }
#define ThrowIfFailed(EXP) DxRoidsAssert((EXP) == S_OK)
#else
#define DxRoidsAssert(EXP)
#define ThrowIfFailed(EXP) if ((EXP) != S_OK) { throw std::runtime_error(#EXP); }
#endif //DEBUG || _DEBUG
#endif


#define DXROIDS_COM_PTR CComPtr

namespace dxroids
{  
   extern D2D1_POINT_2F ScreenSize;
   
   DXROIDS_COM_PTR<ID2D1Factory> const & GetDirect2DFactory();

   enum SoundEffect
   {
      Fire,
      BangLarge,
      BangMedium,
      BangSmall,
      BeatOne,
      BeatTwo,
      ExtraShip,
      SaucerBig,
      SaucerSmall,
      Thrust         
   };

   class SoundManager;

   inline /* constexpr */ float DegreesToRadians(float _degrees)
   {
      return _degrees * 0.0174532925f;
   }  

   enum ScreenEdge
   {
      Top = 1,
      Bottom = 2,
      Left = 3,
      Right = 4
   };

   enum ScreenCorner
   {
      TopLeft = 1,
      TopRight = 2,
      BottomLeft = 3,
      BottomRight = 4
   };   

   struct ClippingInformation
   {
      float x;
      float y;
   };

   inline D2D1_POINT_2F make_point(float _x, float _y, float _scale)
   {     
      D2D1_POINT_2F temp;
      temp.x = _x * _scale;
      temp.y = _y * _scale;
      return temp;
   }
}

// #define DXROIDS_DEBUG_COLLISIONS 
// #define DXROIDS_GAMEPAD_ENABLED

#define DXROIDS_MATH_PI 3.14159f
#define DXROIDS_MATH_PI_OVER_2 1.57079f
#define DXROIDS_MATH_PI_OVER_4 0.78539f

#define DXROIDS_APPLICATION_DPI 96.0f
#define DXROIDS_APPLICATION_SCREEN_WIDTH 1200.0f
#define DXROIDS_APPLICATION_SCREEN_HEIGHT 1000.0f // 768.0f
#define DXROIDS_APPLICATION_THUMPS_PER_SECOND 0.5f
#define DXROIDS_APPLICATION_FRAMES_PER_SECOND 60

#define DXROIDS_SCORE_BIG_ROCK 15
#define DXROIDS_SCORE_MEDIUM_ROCK 50
#define DXROIDS_SCORE_SMALL_ROCK 100
#define DXROIDS_SCORE_ENEMY_SHIP_SMALL 500
#define DXROIDS_SCORE_ENEMY_SHIP_LARGE 100

#define DXROIDS_PLAYER_SHIP_MAXVELOCITY 14.0f
#define DXROIDS_PLAYER_SHIP_MAXVELOCITY_SQUARED (DXROIDS_PLAYER_SHIP_MAXVELOCITY * DXROIDS_PLAYER_SHIP_MAXVELOCITY)
#define DXROIDS_PLAYER_SHIP_THRUST_MAGNITUDE 0.2f
#define DXROIDS_PLAYER_SHIP_MAX_SHOTS 3
#define DXROIDS_PLAYER_SHIP_ROTATIONAL_VELOCITY 4.0f
#define DXROIDS_PLAYER_SHIP_SECONDS_IN_HYPERSPACE 2
#define DXROIDS_PLAYER_SHIP_HYPERSPACE_CONSTRAINT 0.85f
#define DXROIDS_PLAYER_SHIP_PHOTON_MAX_DISTANCE 600.0f
#define DXROIDS_PLAYER_SHIP_PHOTON_VELOCITY 10.0f

#define DXROIDS_SPACE_ROCK_ROTATIONAL_VELOCITY_MIN 0.8f
#define DXROIDS_SPACE_ROCK_ROTATIONAL_VELOCITY_MAX 1.4f
#define DXROIDS_SPACE_ROCK_SLOW_VELOCITY 1.0f
#define DXROIDS_SPACE_ROCK_OFFSCREEN_OFFSET 80.0f

#define DXROIDS_CHARACTER_HEIGHT 8.0f
#define DXROIDS_CHARACTER_WIDTH 6.0f

#define DXROIDS_ENEMY_SHIP_VELOCITY 5.0f
#define DXROIDS_ENEMY_SHIP_TARGET_SKEW 0.1f

#define DXROIDS_EXPLOSION_NUM_POINTS 10
#define DXROIDS_EXPLOSTION_DIAMETER 1
#define DXROIDS_EXPLOSION_PARTICLE_VELOCITY 1.0f
#define DXROIDS_EXPLOSION_PARTICLE_JITTER_MIN 0.8f
#define DXROIDS_EXPLOSION_PARTICLE_JITTER_MAX 1.1f
#define DXROIDS_EXPLOSION_MAX_RADIUS 35.0f

#define DXROIDS_PARTICLE_RADIUS 1.0f


